home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARGONET / PD / FILER / TARSRC.SPK / c / replace < prev    next >
Text File  |  1994-08-05  |  10KB  |  331 lines

  1.  
  2. #include "tar.h"
  3. #include "args.h"
  4. #include "timecon.h"
  5. #include "perms.h"
  6. #include "dir.h"
  7. #include "disc.h"
  8. #include "tapeio.h"
  9. #include "replace.h"
  10.  
  11.  
  12. /* replace and create routines */
  13.  
  14.  
  15. static void tomodes(CatInfo *InfoBlk, int mode) {
  16.   memset(Block.Block,0,RECORDSIZE);
  17.   sprintf(Block.Header.mode, "%6o",mode);
  18.   sprintf(Block.Header.uid, "%6o", 0);
  19.   sprintf(Block.Header.gid, "%6o", 0);
  20.   sprintf(Block.Header.mtime, "%11lo",
  21.           fs_to_unix_time((unsigned char *)&InfoBlk->DateAndName));
  22.   if (!UnixArchive) {
  23.     sprintf(Block.Header.magic, "%s", ARC_MAGIC);
  24.     sprintf(Block.Header.LoadAddress,"%11lo", InfoBlk->LoadAddress);
  25.     sprintf(Block.Header.ExecAddress,"%11lo", InfoBlk->ExecAddress);
  26.     sprintf(Block.Header.Attr,"%11lo", InfoBlk->Attr);
  27.     sprintf(Block.Header.Date,"%2.2x %8.8lx",(int)InfoBlk->DateAndName[4],
  28.             *(long *)&InfoBlk->DateAndName);
  29.   }
  30. } /* tomodes */
  31.  
  32.  
  33. static void PutObject(char *longname, char *ShortName, char *parent) {
  34.   int i, compressed, ExtentNo, bytes;
  35.   long restlength, freespace, extentlength;
  36.   char *cp, *filename;
  37.   long blocks;
  38.   FILE *infile;
  39.   os_gbpbstr blk;
  40.   CatInfo InfoBuf;
  41.   char buf[RECORDSIZE];
  42.   char newparent[NAMSIZ+64];
  43.   os_regset regs;
  44.  
  45.   if (ConfirmActions && !QuietExecution) {
  46.     fprintf(stderr, "tar: %s: ",longname);
  47.     if (Decision('y') == 'n') {
  48.       return;
  49.     }
  50.   }
  51.   blk.action = 11 /* OSGBPB_ReadDirEntriesCatInfo */;
  52.   blk.file_handle = (int) parent;
  53.   blk.data_addr = (void *)&InfoBuf;
  54.   blk.seq_point = 0;
  55.   blk.buf_len = sizeof(struct catinfo);
  56.   blk.wild_fld = ShortName;
  57.   do {
  58.     blk.number = 32767 /* 77 - blk.seq_point */;
  59.     chkos(os_gbpb(&blk));
  60.   } while (blk.number == 0 && blk.seq_point > 0);
  61.   if (blk.number != 1) {
  62.     fprintf(stderr, "tar: %s: info not found\n", longname);
  63.     return;
  64.   }
  65.  
  66.   switch ((ObjectType)InfoBuf.Type) {
  67.     case t_DirFound:
  68.       if (MultipleVolumes) {
  69.         freespace = FreeOnTape()-2*RECORDSIZE;
  70.         if (freespace < 0)
  71.           NewDisc();
  72.       }
  73.       for (i = 0, cp = buf; *cp = longname[i++], *cp++;)
  74.         ;
  75.       *--cp = FS_DIRSEP;
  76.       *++cp = 0;
  77.       if ((cp - buf) >= NAMSIZ) {
  78.         fprintf(stderr, "tar: %s: file name too long\n",longname);
  79.         return;
  80.       }
  81.       InfoBuf.Length = 0;
  82.       tomodes(&InfoBuf,unix_dir_perms(InfoBuf.Attr));
  83.       sprintf(Block.Header.size, "%11lo", (long)0);
  84.       strcpy(Block.Header.name,buf);
  85.       if (!UnixArchive || name_to_unix(Block.Header.name)) {
  86.         if (!UnixArchive)
  87.           Block.Header.archieflag = ARC_FLAG;    
  88.         Block.Header.linkflag = LF_DIR;
  89.         sprintf(Block.Header.chksum, "%6o", checksum(&Block));
  90.         writetape((char *)&Block);
  91.       }
  92.       sprintf(newparent, "%s%c%s", parent, FS_DIRSEP, ShortName);
  93. #if WITH_PWD
  94.       ChangeCurrentDir(ShortName);
  95. #endif
  96.       blk.file_handle = (int) newparent;
  97.       blk.seq_point = 0;
  98.       blk.wild_fld = "*";
  99.       do {
  100.         blk.number = 1;
  101.         chkos(os_gbpb(&blk));
  102.         if (blk.number == 1 && !UserInterrupt) {
  103.           strcpy(cp, (char *)&InfoBuf.DateAndName[5]);
  104.           PutObject(buf, cp, newparent);
  105.         }
  106.       } while (blk.seq_point > 0 && !UserInterrupt);
  107. #if WITH_PWD
  108.       ChangeCurrentDir(parent);
  109. #endif
  110.       break;
  111.  
  112.     case t_FileFound:
  113.     case t_ImageFileFound:
  114.       compression = 0;
  115.       if (CompressFiles && InfoBuf.Length > RECORDSIZE) {
  116.         if (ExecuteCommand(CompressTemplate,ShortName,ScrapNameZ,0)) {
  117.           regs.r[0] = 5;
  118.           regs.r[1] = (int)ScrapNameZ;
  119.           if (os_swix(OS_File,®s) == NULL &&
  120.               (ObjectType)regs.r[0] == t_FileFound)
  121.             compression = (int)((long)100-
  122.                                 (long)regs.r[4]*(long)100/InfoBuf.Length);
  123.         }
  124.       }
  125.       if (compression > 0) {
  126.         InfoBuf.Length = (long)regs.r[4];
  127.         filename = ScrapNameZ;
  128.         compressed = 1;
  129.       } else {
  130.         filename = ShortName;
  131.         compressed = 0;
  132.       }
  133.       if (strlen(longname) >= NAMSIZ) {
  134.         fprintf(stderr, "tar: %s: file name too long\n",longname);
  135.         return;
  136.       }
  137.       if ((infile = fopen(filename, "rb")) == NULL) {
  138.         fprintf(stderr, "tar: %s: cannot open file\n", filename);
  139.         return;
  140.       }
  141.       tomodes(&InfoBuf,fs_to_unix_perms(InfoBuf.Attr, InfoBuf.LoadAddress));
  142.       sprintf(Block.Header.compression,"%11o ",compression);
  143.       strcpy(Block.Header.name, longname);
  144.       if (UnixArchive) {
  145.         if (!name_to_unix(Block.Header.name)) {
  146.           return;
  147.         }
  148.         if (AddFileTypeExtension && (InfoBuf.LoadAddress & 0xFFF00000)) {
  149.           sprintf(Block.Header.name + strlen(Block.Header.name), ".%s",
  150.             FileTypeName((int)(InfoBuf.LoadAddress >> 8) & 0xFFF));
  151.         }
  152.         if (CommaFileTypes && (InfoBuf.LoadAddress & 0xFFF00000) &&
  153.             ((InfoBuf.LoadAddress >> 8) & 0xFFF) != ft_Text) {
  154.           sprintf(Block.Header.name + strlen(Block.Header.name), ",%.3lX",
  155.             (InfoBuf.LoadAddress >> 8) & 0xFFF);
  156.         }
  157.       } else {
  158.         Block.Header.archieflag = ARC_FLAG;
  159.       }
  160.       if (compressed)
  161.         Block.Header.compressed =  CF_COMPRESSED;
  162.       restlength = InfoBuf.Length;
  163.       ExtentNo = 0;
  164.       do {
  165.         extentlength = restlength;
  166.         if (MultipleVolumes) {
  167.           freespace = FreeOnTape()-2*RECORDSIZE;
  168.           if (extentlength > freespace) {
  169.             if (freespace < extentlength/10 && freespace < MAXUNUSED) {
  170.               NewDisc();
  171.               freespace = FreeOnTape()-2*RECORDSIZE;
  172.             }
  173.             extentlength = freespace;
  174.             if (extentlength > restlength)
  175.               extentlength = restlength;
  176.             if (ExtentNo > 0 || extentlength < restlength)
  177.               ExtentNo++;
  178.           }
  179.         }
  180.         sprintf(Block.Header.size, "%11lo", extentlength);
  181.         if (ExtentNo > 0) {
  182.           Block.Header.linkflag = (extentlength == restlength)
  183.                                  ? LF_LASTEXTENT : LF_EXTENT;
  184.           sprintf(Block.Header.ExtentNo,"%6o",ExtentNo);
  185.         } else {
  186.           Block.Header.linkflag = LF_NORMAL;
  187.         }
  188.         blocks = (extentlength + (RECORDSIZE-1)) / RECORDSIZE;
  189.         if (Verbose) {
  190.           if (tapedevice == tapedevice_DISC || MultipleVolumes)
  191.             fprintf(stderr,"%3ldK ",FreeOnTape()/(long)1024);
  192.           fprintf(stderr,"a ");
  193.           if (CompressFiles) {
  194.             if (compressed)
  195.               fprintf(stderr,"%2d%% ",compression);
  196.             else
  197.               fprintf(stderr,"    ");
  198.           }
  199.           fprintf(stderr,"%s, %ld bytes, ",longname,extentlength);
  200.           PrintBlocks(stderr,blocks);
  201.           if (ExtentNo > 0)
  202.             fprintf(stderr," (extent #%d)",ExtentNo);
  203.           fputc('\n',stderr);
  204.         }
  205.         sprintf(Block.Header.chksum, "%6o", checksum(&Block));
  206.         writetape((char *)&Block);
  207.         while (blocks > 0 && (bytes = fread(&buf,1,RECORDSIZE,infile)) > 0) {
  208.           if (bytes < RECORDSIZE)
  209.             memset(buf+bytes, 0, RECORDSIZE-bytes);
  210.           writetape(buf);
  211.           blocks--;
  212.         }
  213.         restlength -= extentlength;
  214.       } while (restlength > 0 && !UserInterrupt);
  215.       fclose(infile);
  216.       if (blocks != 0)
  217.         fprintf(stderr, "tar: %s: file not complete\n",longname);
  218.       while (--blocks >=  0)
  219.         putempty();
  220.       if (CompressFiles)
  221.         compress_cleanup();
  222.       break;
  223.  
  224.     default:
  225.       fprintf(stderr, "tar: %s is not a file. Not dumped\n",longname);
  226.       break;
  227.   }
  228. } /* PutObject */
  229.  
  230.  
  231. void ReplaceFiles(void) {
  232.   char *cp, *cp2, *OrgLeafName, *LeafBrowse;
  233.   os_gbpbstr DirBlk;
  234.   CatInfo InfoBuf;
  235. #if WITH_PWD
  236.   char parent[256], *tmp;
  237.   char wdir[MAXPATHLEN], tempdir[MAXPATHLEN];
  238.   char RealName[MAXPATHLEN], longname[MAXPATHLEN];
  239. #endif
  240.  
  241.   if (!CreateArchive) {
  242.     while (!UserInterrupt) {
  243.       getdir(&InfoBuf);
  244.       if (endtape())
  245.         break;
  246.       switch (Block.Header.linkflag) {
  247.         case LF_LASTEXTENT:
  248.         case LF_EXTENT:
  249.         case LF_NORMAL:
  250.         case LF_OLDNORMAL:
  251.         case LF_DIR:
  252.           passtape(InfoBuf.Length);
  253.           break;
  254.         default:
  255.           break;
  256.       }
  257.     }
  258.     if (UserInterrupt)
  259.       return;
  260.     backtape();
  261.   }
  262.  
  263. #if WITH_PWD
  264.   GetCurrentDir(wdir);
  265. #endif
  266.   while (!UserInterrupt && (cp2 = GetArg(1), cp2)) {
  267. #if WITH_PWD
  268.     if (!strcmp(cp2, "-C") && (cp2 = GetArg(1), cp2)) {
  269. #if WITH_PWD
  270.       ChangeCurrentDir(cp2);
  271.       (void)GetCurrentDir(wdir);
  272. #else
  273.       
  274. #endif
  275.       continue;
  276.     }
  277. #endif
  278. #if WITH_PWD
  279.     strcpy(parent, wdir);
  280. #endif
  281.     strcpy(longname,cp2);
  282.     OrgLeafName = cp2;
  283.     cp2 = longname;
  284.     LeafBrowse = OrgLeafName;
  285.     for (cp = longname; *cp; cp++, LeafBrowse++)
  286.       if (*cp == FS_DIRSEP) {
  287.         cp2 = cp;
  288.         OrgLeafName = LeafBrowse;
  289.       }
  290.     if (cp2 != longname) {
  291.       *cp2 = '\0';
  292. #if WITH_PWD
  293.       ChangeCurrentDir(longname);
  294.       if ((tmp = GetCurrentDir(tempdir)) == NULL) {
  295.         strcpy(parent, longname);
  296.       } else {
  297.         strcpy(parent, tmp);
  298.       }
  299. #endif
  300.       *cp2 = FS_DIRSEP;
  301.       cp2++;
  302.       OrgLeafName++;
  303.     }
  304.     DirBlk.action = 9;
  305.     DirBlk.file_handle = (int)parent;
  306.     DirBlk.data_addr = (void *)&RealName;
  307.     DirBlk.seq_point = 0;
  308.     DirBlk.buf_len = sizeof(RealName);
  309.     DirBlk.wild_fld = OrgLeafName;
  310.     do {
  311.       DirBlk.number = 1;
  312.       chkos(os_gbpb(&DirBlk));
  313.       if (DirBlk.number == 1 && !UserInterrupt) {
  314.         if (cp2 != longname) {
  315.           *cp2 = '\0';
  316.           strcat(longname,RealName);
  317.         } else {
  318.           strcpy(longname,RealName);
  319.         }
  320.         PutObject(longname, RealName, parent);
  321.       }
  322.     } while (DirBlk.seq_point > 0 && !UserInterrupt);
  323. #if WITH_PWD
  324.     ChangeCurrentDir(wdir);
  325. #endif
  326.   }
  327.   putempty();
  328.   putempty();
  329.   flushtape();
  330. } /* ReplaceFiles */
  331.